﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using EasyDapr.Infrastructure.Attribute;
using Microsoft.Extensions.DependencyInjection;

namespace EasyDapr.Infrastructure.Dapr
{
    public static class Extensions
    {
        public static IServiceCollection AddCustomDaprClient(this IServiceCollection services)
        {
            var options = new JsonSerializerOptions()
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase, PropertyNameCaseInsensitive = true,
            };

            services.AddSingleton(options);

            services.AddDaprClient(client => { client.UseJsonSerializationOptions(options); });

            return services;
        }

        public static IServiceCollection AddCustomDaprComponent<TType>(this IServiceCollection services,
            Assembly[] assemblies = null)
        {
            var list = new List<Assembly>
            {
                typeof(TType).Assembly
            };
            if (assemblies != null && assemblies.Length > 0)
            {
                list.AddRange(assemblies);
            }
            foreach (var type in list.SelectMany(assembly => assembly.GetTypes().Where(IsDaprComponent)))
            {
                services.AddTransient(type);
            }

            return services;
        }

        /// <summary>
        /// Check whether a type is a component type.
        /// </summary>
        private static bool IsDaprComponent(Type type)
        {
            return type.IsClass && !type.IsAbstract &&
                   type.GetCustomAttributes(typeof(DaprComponentAttribute), false).Any();
        }
    }
}